﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Concurrent;

namespace CostomGameServer
{
	/// <summary>
	/// 一个简易的数据帧对象池
	/// </summary>
	class DataFramePool
	{
		//实现单例模式
		static readonly DataFramePool dataFramePool = new DataFramePool( );

		static int timestampCurrent;
		static Package pkgCurrent;//服务器当前正在处理的数据包，将在下一次通讯发出
		static internal bool isActivated = false;
		static internal bool inGame = false;//若正在进行游戏，则无法将数据包列表序列化到本地文件
		static readonly List<Package> pkgCache = new List<Package>( );//数据帧列表，用来保存游戏对局
		static BinaryFormatter formatter = new BinaryFormatter( );


		static internal void Start() {
			isActivated = true;
			timestampCurrent = 0;
			pkgCurrent = new Package( (byte)PackageType.Action, -1, timestampCurrent );
		}

		static internal void PushCurrent(out Package current) {
			pkgCache.Add( pkgCurrent );
			current = pkgCurrent;
			pkgCurrent = new Package( (byte)PackageType.Action, -1, ++timestampCurrent );
		}

		static internal void Merge(Package pkg) {
			if (pkg.Timestamp < timestampCurrent) {
				UdpManager.SendPackage( pkg );
				pkgCache[ pkg.Timestamp ].ActionFrames.AddRange( pkg.ActionFrames );
			}
			else {
				lock (pkgCurrent) { pkgCurrent.ActionFrames.AddRange( pkg.ActionFrames ); }

			}

		}

		static internal void Merge(byte[ ] buffer) {
			Merge( formatter.Deserialize( new MemoryStream( buffer ) ) as Package );

		}

		static internal bool GetPackageByTime(out Package pkg, int timestamp) {
			if (pkgCache.Count > timestamp) {
				pkg = null;
				return false;
			}
			else {
				pkg = pkgCache[ timestamp ];
				return true;
			}
		}

		static internal Package GetCurrent() {
			return pkgCurrent;
		}

		static internal DataFramePool Instance() {
			return dataFramePool;
		}

		static internal void SavePackageCacheToFile(string path) {
			if (inGame) {
				Console.WriteLine( "Current in game, can't save the game" );
			}
			using (FileStream stream = new FileStream( path, FileMode.OpenOrCreate )) {
				formatter.Serialize( stream, pkgCache );
			}
		}
	}
}
